---
type: tutorial
title: Add dynamic content about you
description: |-
  Tutorial: Build your first Astro blog —
  Use variables and conditional rendering on your Astro pages
i18nReady: true
---
import Checklist from '~/components/Checklist.astro';
import Spoiler from '~/components/Spoiler.astro';
import Blanks from '~/components/tutorial/Blanks.astro';
import Box from '~/components/tutorial/Box.astro';
import MultipleChoice from '~/components/tutorial/MultipleChoice.astro';
import Option from '~/components/tutorial/Option.astro';
import PreCheck from '~/components/tutorial/PreCheck.astro';
import { Steps } from '@astrojs/starlight/components';

Now that you have a multi-page website with HTML content, it's time to add some dynamic HTML!

<PreCheck>
  - Define your page title in frontmatter, and use it in your HTML
  - Conditionally display HTML elements
  - Add some content about you
</PreCheck>

Any HTML file is valid Astro language. But, you can do more with Astro than just regular HTML!

## Define and use a variable

Open `about.astro`, which should look like this:

```astro title="src/pages/about.astro"
---
---
<html lang="en">
  <head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width" />
    <title>Astro</title>
  </head>
  <body>
    <a href="/">Home</a>
    <a href="/about/">About</a>
    <a href="/blog/">Blog</a>
    <h1>About Me</h1>
    <h2>... and my new Astro site!</h2>

    <p>I am working through Astro's introductory tutorial. This is the second page on my website, and it's the first one I built myself!</p>

    <p>This site will update as I complete more of the tutorial, so keep checking back and see how my journey is going!</p>
  </body>
</html>
```

<Steps>
1. Add the following line of JavaScript in the frontmatter script, between the **code fences**:

    ```astro title="src/pages/about.astro" ins={2}
    ---
    const pageTitle = "About Me";
    ---
    ```

2. Replace both the static "Astro" title and "About Me" heading in your HTML with the dynamic variable `{pageTitle}`.

    ```astro title="src/pages/about.astro" del={5,12} ins={6,13}
    <html lang="en">
      <head>
        <meta charset="utf-8" />
        <meta name="viewport" content="width=device-width" />
        <title>Astro</title>
        <title>{pageTitle}</title>
      </head>
      <body>
        <a href="/">Home</a>
        <a href="/about/">About</a>
        <a href="/blog/">Blog</a>
        <h1>About Me</h1>
        <h1>{pageTitle}</h1>
        <h2>... and my new Astro site!</h2>

        <p>I am working through Astro's introductory tutorial. This is the second page on my website, and it's the first one I built myself!</p>

        <p>This site will update as I complete more of the tutorial, so keep checking back and see how my journey is going!</p>
      </body>
    </html>
    ```

3. Refresh the live preview of your `/about` page.
  
    Your page text should look the same, and your page title displayed in your browser tab should now read "About Me" instead of "Astro." 

    Instead of typing text directly into HTML tags, you just **defined and then used a variable** in the two sections of your `.astro` file, respectively.

4. Use the same pattern to create a `pageTitle` value to use in `index.astro` ("Home Page") and `blog.astro` ("My Astro Learning Blog"). Update the HTML of these pages in both places so that your page title matches the heading displayed on each page.
</Steps>

:::note[Takeaways]
1. **Define** variables in your Astro script using JavaScript or TypeScript expressions.
2. **Use** these variables in your Astro template inside curly braces `{ }` to tell Astro you're using some JavaScript.
:::

## Write JavaScript expressions in Astro

<Steps>
1. Add the following JavaScript to your frontmatter, between the **code fences**:

      (You can customize the code for yourself, but this tutorial will use the following example.)

    ```astro title="src/pages/about.astro" ins={4-9, 11}
    ---
    const pageTitle = "About Me";

    const identity = {
      firstName: "Sarah",
      country: "Canada",
      occupation: "Technical Writer",
      hobbies: ["photography", "birdwatching", "baseball"],
    };

    const skills = ["HTML", "CSS", "JavaScript", "React", "Astro", "Writing Docs"];
    ---
    ```

2. Then, add the following code to your HTML template, below your existing content:

    ```astro title="src/pages/about.astro"
    <p>Here are a few facts about me:</p>
    <ul>
      <li>My name is {identity.firstName}.</li>
      <li>I live in {identity.country} and I work as a {identity.occupation}.</li>
      {identity.hobbies.length >= 2 && 
        <li>Two of my hobbies are: {identity.hobbies[0]} and {identity.hobbies[1]}</li>
      } 
    </ul>
    <p>My skills are:</p>
    <ul>
      {skills.map((skill) => <li>{skill}</li>)}
    </ul>
    ```
</Steps>

:::note[Takeaways]
1. Writing an Astro template is very much like **writing HTML**, but you can include JavaScript expressions within it.
2. The Astro frontmatter script contains only JavaScript. 
3. You can use all modern JavaScript **logical operators**, **expressions** and **functions** in either section of your `.astro` file. But, curly braces are necessary (only) in the HTML template body.
:::

<Box icon="question-mark">

### Test your knowledge

1. A `.astro` file's frontmatter is written in:

    <MultipleChoice>
        <Option>HTML</Option>
        <Option>YAML</Option>
        <Option isCorrect>JavaScript</Option>
    </MultipleChoice>

2. In addition to HTML, Astro syntax allows you to include:

    <MultipleChoice>
        <Option isCorrect>JavaScript logical operators, expressions and functions</Option>
        <Option>YAML</Option>
        <Option>Markdown</Option>
    </MultipleChoice>

3. When do you need to write your JavaScript inside curly braces?
    <MultipleChoice>
        <Option>
          When you're not sure whether it's correct.
        </Option>
        <Option isCorrect>
          When inside the HTML template section of an Astro component.
          </Option>
        <Option>
          Between the code fences in an Astro component.
        </Option>
    </MultipleChoice>
</Box>

## Conditionally render elements

You can also use your script variables to choose **whether or not** to render individual elements of your HTML `<body>` content.

<Steps>
1. Add the following lines to your frontmatter script to **define variables**:

    ```astro title="src/pages/about.astro" ins={13-15}
    ---
    const pageTitle = "About Me";

    const identity = {
      firstName: "Sarah",
      country: "Canada",
      occupation: "Technical Writer",
      hobbies: ["photography", "birdwatching", "baseball"],
    };

    const skills = ["HTML", "CSS", "JavaScript", "React", "Astro", "Writing Docs"];

    const happy = true;
    const finished = false;
    const goal = 3;
    ---
    ```

2. Add the following lines below your existing paragraphs.

    Then, check the live preview in your browser tab to see what is displayed on the page:

    ```astro title="src/pages/about.astro" /:|&&/ "?"
    {happy && <p>I am happy to be learning Astro!</p>}

    {finished && <p>I finished this tutorial!</p>}

    {goal === 3 ? <p>My goal is to finish in 3 days.</p> : <p>My goal is not 3 days.</p>}
    ```

3. Commit your changes to GitHub before moving on. Do this any time you want to save your work and update your live website.
</Steps>

:::tip
Astro's templating syntax is similar to JSX syntax. If you're ever wondering how to use your script in your HTML, then searching for how it is done in JSX is probably a good starting point!
:::



<Box icon="question-mark">

### Analyze the Pattern

Given the following `.astro` script:

```astro title="src/pages/about.astro"
---
const operatingSystem = "Linux";
const quantity = 3;
const footwear = "boots";
const student = false;
---
```


For each Astro template expression, can you predict the HTML (if any!) that will be sent to the browser? Click to reveal if you're right!

1.  `<p>{operatingSystem}</p>`

    <p>
      <Spoiler>`<p>Linux</p>`</Spoiler>
    </p>

2.  `{student && <p>I am still in school.</p>}`

    <p>
      <Spoiler>Nothing will display because `student` evaluates to false.</Spoiler>
    </p>

3.  `<p>I have {quantity + 8} pairs of {footwear}</p>`

    <p>
      <Spoiler>`<p>I have 11 pairs of boots</p>`</Spoiler>
    </p>

4.  `{operatingSystem === "MacOS" ? <p>I am using a Mac.</p> : <p>I am not using a Mac.</p>}`

    <p>
      <Spoiler>`<p>I am not using a Mac.</p>`</Spoiler>
    </p>
</Box>


<Box icon="check-list">
## Checklist

<Checklist>
- [ ] I can define values in and use values in `.astro` files.
- [ ] I can conditionally render HTML elements.
</Checklist>
</Box>


### Resources

- [Dynamic expressions in Astro](/en/reference/astro-syntax/#jsx-like-expressions)
